package com.py.credit.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.alibaba.fastjson.JSONArray;
import com.py.credit.common.ServiceException;
import com.py.credit.constant.OrgConstant;
import com.py.credit.dao.AccountDao;
import com.py.credit.dao.ElementDao;
import com.py.credit.dao.OrgDao;
import com.py.credit.dao.PersonnelDao;
import com.py.credit.entity.Account;
import com.py.credit.entity.Element;
import com.py.credit.entity.Organization;
import com.py.credit.entity.Personnel;
import com.py.credit.entity.ShareHolder;
import com.py.credit.service.ModelBaseService;
import com.py.credit.service.OrgService;
import com.py.credit.utils.SQLBuilder;
import com.py.credit.utils.UuidUtil;
import com.py.framework.core.common.Page;

@Service
public class OrgserviceImpl implements OrgService {

	private static final Logger LOG = Logger.getLogger(OrgserviceImpl.class);

	@Autowired
	private OrgDao orgDao;

	@Autowired
	private AccountDao accountDao;

	@Autowired
	private PersonnelDao perDao;

	@Autowired
	private ElementDao elementDao;

	@Autowired
	private ModelBaseService modelBaseService;

	@Value("${org.resource.path}")
	private String orgResourceBasePath;

	@Override
	@Transactional
	public String addOrg(Organization org, Account account, CommonsMultipartFile businessLicenceFile,
			CommonsMultipartFile commitmentLetterFile, CommonsMultipartFile orgCodeCertificateFile,
			CommonsMultipartFile taxRegisterLicenceFile, CommonsMultipartFile accountCertificateFile,
			CommonsMultipartFile regulatorFile, CommonsMultipartFile orgCrSample) throws Exception {

		// 验重

		if (accountDao.selectCountByAccount(account.getAccount()) > 0) {

			throw new ServiceException("账号已存在");

		}

		if (orgDao.selectCountByOrgName(org.getOrgName()) > 0) {

			throw new ServiceException("机构已存在");

		}

		String orgId = UuidUtil.getUUid();

		org.setOrgId(orgId);
		account.setOrgId(orgId);
		account.setType(OrgConstant.ACCOUNT_TYPE_PRIMARY);
		String orgResourcePath = orgResourceBasePath + File.separator + orgId + File.separator + "org";

		File dir = new File(orgResourcePath);

		if (!dir.exists()) {

			dir.mkdirs();

		}

		org.setTaxRegisterLicence(File.separator + orgId + File.separator + "org" + File.separator + "TRL_"
				+ taxRegisterLicenceFile.getOriginalFilename());
		org.setBusinessLicence(File.separator + orgId + File.separator + "org" + File.separator + "BL_"
				+ businessLicenceFile.getOriginalFilename());
		org.setCommitmentLetter(File.separator + orgId + File.separator + "org" + File.separator + "CL_"
				+ commitmentLetterFile.getOriginalFilename());
		org.setAccountCertificate(File.separator + orgId + File.separator + "org" + File.separator + "AC_"
				+ accountCertificateFile.getOriginalFilename());
		org.setOrgCodeCertificate(File.separator + orgId + File.separator + "org" + File.separator + "ORC_"
				+ orgCodeCertificateFile.getOriginalFilename());
		org.setOrgCrSample(File.separator + orgId + File.separator + "org" + File.separator + "OCS_"
				+ orgCrSample.getOriginalFilename());

		if (regulatorFile != null) {

			org.setRegulator(File.separator + orgId + File.separator + "org" + File.separator + "RE_"
					+ regulatorFile.getOriginalFilename());
			regulatorFile.transferTo(
					new File(orgResourcePath + File.separator + "RE_" + regulatorFile.getOriginalFilename()));
		}

		businessLicenceFile.transferTo(
				new File(orgResourcePath + File.separator + "BL_" + businessLicenceFile.getOriginalFilename()));

		commitmentLetterFile.transferTo(
				new File(orgResourcePath + File.separator + "CL_" + commitmentLetterFile.getOriginalFilename()));

		orgCodeCertificateFile.transferTo(
				new File(orgResourcePath + File.separator + "ORC_" + orgCodeCertificateFile.getOriginalFilename()));

		taxRegisterLicenceFile.transferTo(
				new File(orgResourcePath + File.separator + "TRL_" + taxRegisterLicenceFile.getOriginalFilename()));

		accountCertificateFile.transferTo(
				new File(orgResourcePath + File.separator + "AC_" + accountCertificateFile.getOriginalFilename()));

		orgCrSample.transferTo(new File(orgResourcePath + File.separator + "OCS_" + orgCrSample.getOriginalFilename()));

		orgDao.add(org);

		accountDao.add(account);

		return orgId;

	}

	@Override
	public void modifyOrg(Organization org, CommonsMultipartFile businessLicenceFile,
			CommonsMultipartFile commitmentLetterFile, CommonsMultipartFile orgCodeCertificateFile,
			CommonsMultipartFile taxRegisterLicenceFile, CommonsMultipartFile accountCertificateFile,
			CommonsMultipartFile regulatorFile, CommonsMultipartFile orgCrSample) throws Exception {

		String orgId = org.getOrgId();

		if (!StringUtils.isBlank(orgId)) {

			String orgResourcePath = orgResourceBasePath + File.separator + orgId + File.separator + "org";

			File dir = new File(orgResourcePath);

			if (!dir.exists()) {

				dir.mkdirs();

			}

			if (taxRegisterLicenceFile != null) {

				org.setTaxRegisterLicence(File.separator + orgId + File.separator + "org" + File.separator + "TRL_"
						+ taxRegisterLicenceFile.getOriginalFilename());

				taxRegisterLicenceFile.transferTo(new File(
						orgResourcePath + File.separator + "TRL_" + taxRegisterLicenceFile.getOriginalFilename()));

			}
			if (businessLicenceFile != null) {
				org.setBusinessLicence(File.separator + orgId + File.separator + "org" + File.separator + "BL_"
						+ businessLicenceFile.getOriginalFilename());
				businessLicenceFile.transferTo(
						new File(orgResourcePath + File.separator + "BL_" + businessLicenceFile.getOriginalFilename()));
			}

			if (commitmentLetterFile != null) {
				org.setCommitmentLetter(File.separator + orgId + File.separator + "org" + File.separator + "CL_"
						+ commitmentLetterFile.getOriginalFilename());
				commitmentLetterFile.transferTo(new File(
						orgResourcePath + File.separator + "CL_" + commitmentLetterFile.getOriginalFilename()));
			}

			if (accountCertificateFile != null) {
				org.setAccountCertificate(File.separator + orgId + File.separator + "org" + File.separator + "AC_"
						+ accountCertificateFile.getOriginalFilename());

				accountCertificateFile.transferTo(new File(
						orgResourcePath + File.separator + "AC_" + accountCertificateFile.getOriginalFilename()));
			}

			if (orgCodeCertificateFile != null) {
				org.setOrgCodeCertificate(File.separator + orgId + File.separator + "org" + File.separator + "ORC_"
						+ orgCodeCertificateFile.getOriginalFilename());

				orgCodeCertificateFile.transferTo(new File(
						orgResourcePath + File.separator + "ORC_" + orgCodeCertificateFile.getOriginalFilename()));
			}

			if (orgCrSample != null) {
				org.setOrgCrSample(File.separator + orgId + File.separator + "org" + File.separator + "OCS_"
						+ orgCrSample.getOriginalFilename());

				orgCrSample.transferTo(
						new File(orgResourcePath + File.separator + "OCS_" + orgCrSample.getOriginalFilename()));
			}

			if (regulatorFile != null) {

				org.setRegulator(File.separator + orgId + File.separator + "org" + File.separator + "RE_"
						+ regulatorFile.getOriginalFilename());
				regulatorFile.transferTo(
						new File(orgResourcePath + File.separator + "RE_" + regulatorFile.getOriginalFilename()));

			}

			orgDao.update(org);

		}

	}

	@Override
	public void addPersonnel(Personnel personnel, CommonsMultipartFile idCardFPic, CommonsMultipartFile idCardBPic,
			CommonsMultipartFile certificationPic) throws Exception {

		String orgId = personnel.getOrgId();

		if (!StringUtils.isBlank(orgId)) {

			perDao.add(personnel);

			Integer id = personnel.getId();

			String personnelResourcePath = orgResourceBasePath + File.separator + orgId + File.separator + "personnel"
					+ File.separator + id;

			File dir = new File(personnelResourcePath);

			if (!dir.exists()) {

				dir.mkdirs();

			}

			personnel.setIdCardFPic(File.separator + orgId + File.separator + "personnel" + File.separator + id
					+ File.separator + "F_" + idCardFPic.getOriginalFilename());

			personnel.setIdCardBPic(File.separator + orgId + File.separator + "personnel" + File.separator + id
					+ File.separator + "B_" + idCardBPic.getOriginalFilename());

			if (certificationPic != null) {

				personnel.setCertification(File.separator + orgId + File.separator + "personnel" + File.separator + id
						+ File.separator + "C_" + certificationPic.getOriginalFilename());
				certificationPic.transferTo(new File(
						personnelResourcePath + File.separator + "C_" + certificationPic.getOriginalFilename()));
			}

			perDao.update(personnel);

			idCardFPic.transferTo(
					new File(personnelResourcePath + File.separator + "F_" + idCardFPic.getOriginalFilename()));

			idCardBPic.transferTo(
					new File(personnelResourcePath + File.separator + "B_" + idCardBPic.getOriginalFilename()));

		}

	}

	@Override
	public void modifyPersonnel(Personnel personnel, CommonsMultipartFile idCardFPic, CommonsMultipartFile idCardBPic,
			CommonsMultipartFile certificationPic) throws Exception {

		String orgId = personnel.getOrgId();

		Integer id = personnel.getId();

		if (!StringUtils.isBlank(orgId) && id != null) {

			String personnelResourcePath = orgResourceBasePath + File.separator + orgId + File.separator + "personnel"
					+ File.separator + id;

			File dir = new File(personnelResourcePath);

			if (!dir.exists()) {

				dir.mkdirs();

			}

			if (certificationPic != null) {

				personnel.setCertification(File.separator + orgId + File.separator + "personnel" + File.separator + id
						+ File.separator + "C_" + certificationPic.getOriginalFilename());
				certificationPic.transferTo(new File(
						personnelResourcePath + File.separator + "C_" + certificationPic.getOriginalFilename()));
			}

			if (idCardFPic != null) {

				personnel.setIdCardFPic(File.separator + orgId + File.separator + "personnel" + File.separator + id
						+ File.separator + "F_" + idCardFPic.getOriginalFilename());
				idCardFPic.transferTo(
						new File(personnelResourcePath + File.separator + "F_" + idCardFPic.getOriginalFilename()));
			}

			if (idCardBPic != null) {
				personnel.setIdCardBPic(File.separator + orgId + File.separator + "personnel" + File.separator + id
						+ File.separator + "B_" + idCardBPic.getOriginalFilename());
				idCardBPic.transferTo(
						new File(personnelResourcePath + File.separator + "B_" + idCardBPic.getOriginalFilename()));
			}

			perDao.update(personnel);

		}

	}

	@Override
	public void addElement(CommonsMultipartFile sysLogo, CommonsMultipartFile scalingSysLogo, String orgId)
			throws Exception {

		Element element = new Element();
		element.setOrgId(orgId);
		String elementResourcePath = orgResourceBasePath + File.separator + orgId + File.separator + "element";

		File dir = new File(elementResourcePath);

		if (!dir.exists()) {

			dir.mkdirs();

		}

		element.setSysLogo(File.separator + orgId + File.separator + "element" + File.separator + "N_"
				+ sysLogo.getOriginalFilename());

		element.setScalingSysLogo(File.separator + orgId + File.separator + "element" + File.separator + "S_"
				+ scalingSysLogo.getOriginalFilename());

		sysLogo.transferTo(new File(elementResourcePath + File.separator + "N_" + sysLogo.getOriginalFilename()));

		scalingSysLogo.transferTo(
				new File(elementResourcePath + File.separator + "S_" + scalingSysLogo.getOriginalFilename()));

		elementDao.add(element);

	}

	@Override
	public void modifyElement(CommonsMultipartFile sysLogo, CommonsMultipartFile scalingSysLogo, String orgId)
			throws Exception {

		Element element = new Element();
		element.setOrgId(orgId);

		String elementResourcePath = orgResourceBasePath + File.separator + orgId + File.separator + "element";

		File dir = new File(elementResourcePath);

		if (!dir.exists()) {

			dir.mkdirs();

		}

		if (sysLogo != null) {
			element.setSysLogo(File.separator + orgId + File.separator + "element" + File.separator + "N_"
					+ sysLogo.getOriginalFilename());
			sysLogo.transferTo(new File(elementResourcePath + File.separator + "N_" + sysLogo.getOriginalFilename()));

		}

		if (scalingSysLogo != null) {
			element.setScalingSysLogo(File.separator + orgId + File.separator + "element" + File.separator + "S_"
					+ scalingSysLogo.getOriginalFilename());

			scalingSysLogo.transferTo(
					new File(elementResourcePath + File.separator + "S_" + scalingSysLogo.getOriginalFilename()));

		}

		elementDao.update(element);

	}

	@Override
	public List<Map<String, Object>> getOrgListByConditionForPage(String orgId, List<String> showColumns,
			String[] additionalColumns, String condition, Page page) {

		if (CollectionUtils.isEmpty(showColumns)) {

			throw new ServiceException("至少选择一列");

		}
		List<String> conditions = SQLBuilder.createConditionSql(condition);

		List<Map<String, Object>> orgs = orgDao.selectOrgListByConditionForPage(orgId, showColumns, additionalColumns,
				page, conditions);

		return orgs;
	}

	@Override
	public Map<String, Object> getDetail(String orgId) {

		Map<String, Object> map = new HashMap<>();

		Organization org = orgDao.select(orgId);

		String shareHolders = org.getShareHolders();

		if (StringUtils.isNotBlank(shareHolders)) {

			try {

				List<ShareHolder> shs = JSONArray.parseArray(shareHolders, ShareHolder.class);

				map.put("shareholders", shs);

			} catch (Exception e) {

				map.put("shareholders", new ArrayList<>(0));

				LOG.error("股东信息转换失败", e);
			}

		}

		List<Personnel> professionals = perDao.selectList(orgId, OrgConstant.PERSONNEL_TYPE_PROFESSIONAL);
		List<Personnel> managers = perDao.selectList(orgId, OrgConstant.PERSONNEL_TYPE_MANAGER);
		map.put("org", org);
		map.put("managers", managers);
		map.put("professionals", professionals);

		return map;
	}

	@Override
	public List<Personnel> getPersonnels(String orgId, String type) {
		List<Personnel> professionals = perDao.selectList(orgId, type);
		return professionals;
	}

	@Override
	public void addAcccount(Account account) {

		accountDao.add(account);

	}

	@Override
	public void deleteAccount(String accountId) {

		accountDao.delete(accountId);

	}

	@Override
	public void updateAccount(String accountId, String status) {
		accountDao.updateStatus(accountId, status);

	}

	@Override
	public boolean isSuspendedAccount(String accountId) {
		Account account = accountDao.select(accountId);
		return account != null && OrgConstant.ACCOUNT_STATUS_SUSPENDED.equals(account.getStatus());
	}

	@Override
	public void resetAccount(String accountId, String password) {
		accountDao.updatePassword(accountId, password);

	}

	@Override
	public List<Map<String, Object>> getAccountListByConditionForPage(String orgId, List<String> showColumns,
			String[] additionalColumns, String condition, Page page) {

		if (CollectionUtils.isEmpty(showColumns)) {

			throw new ServiceException("至少选择一列");

		}
		List<String> conditions = SQLBuilder.createConditionSql(condition);

		List<Map<String, Object>> orgs = orgDao.selectAccountListByConditionForPage(orgId, showColumns,
				additionalColumns, page, conditions);

		return orgs;
	}

	@Override
	public byte[] getPic(String path) throws Exception {

		String imagePath = orgResourceBasePath + path;

		File file = new File(imagePath);

		if (!file.exists() || StringUtils.isBlank(path)) {

			throw new ServiceException("暂无图片");
		}

		return IOUtils.toByteArray(new FileInputStream(file));

	}

	@Override
	public Personnel getPersonnelById(String perId) {

		return perDao.selectById(perId);
	}

	@Override
	public Organization getOrgById(String id) {

		return orgDao.select(id);
	}

	@Override
	public Account getAccount(String userName, String password) {

		return accountDao.selectBy(userName, password);
	}

	@Override
	public List<Organization> getOrgList(String name) {

		return orgDao.selectOrgList(name);
	}

	@Override
	public List<Organization> getOrgListForPage(String name, Page page, String modelId) {

		return orgDao.selectAllOrgList(name, page, modelId);
	}

	@Override
	public void addModelOrg(String[] modelIds, String[] orgIds, String type) {

		if ("1".equals(type)) {

			orgDao.deleteByModelId(modelIds);

		} else if ("2".equals(type)) {

			orgDao.deleteByOrglId(orgIds);
		}

		for (String modelId : modelIds) {

			orgDao.addModelOrg(modelId, orgIds);

		}

	}

	@Override
	public List<Map<String, Object>> getOrgListByModelIdForPage(String id, String orgName, Page page) {

		return orgDao.selectOrgListByModelIdForPage(id, orgName, page);
	}

	@Override
	public List<Map<String, Object>> getModelListByOrgIdForPage(String id, String modelName, Page page) {

		return orgDao.selectModelListByOrgIdForPage(id, modelName, page);
	}

	@Override
	public List<Map<String, Object>> getActivityByConditionForPage(List<String> showColumns, String[] additionalColumns,
			String condition, Page page, String orgId, String checkType) {

		if (CollectionUtils.isEmpty(showColumns)) {

			throw new ServiceException("至少选择一列");

		}
		List<String> conditions = SQLBuilder.createConditionSql(condition);

		return orgDao.selectActivityByConditionForPage(showColumns, additionalColumns, conditions, page, orgId,
				checkType);
	}

	@Override
	public Element getElement(String orgId) {

		return elementDao.selectElement(orgId);
	}

	@Override
	public void deletePersonnels(String id) {
		perDao.delete(id);

	}

	@Override
	@Transactional
	public void batchAddModelOrg(String[] modelIds) {

		//

		List<Organization> selectOrgList = orgDao.selectOrgList(null);

		int size = selectOrgList.size();

		String[] orgIds = new String[size];

		for (int i = 0; i < size; i++) {

			orgIds[i] = selectOrgList.get(i).getOrgId();

		}

		// delete

		orgDao.deleteByModelId(modelIds);

		for (String modelId : modelIds) {

			orgDao.addModelOrg(modelId, orgIds);

		}

	}

	@Override
	public void batchAddOrgModel(String[] orgIds) {

		List<Map<String, Object>> selectOrgList = modelBaseService.getModelList(null);

		int size = selectOrgList.size();

		String[] modelIds = new String[size];

		for (int i = 0; i < size; i++) {

			modelIds[i] = selectOrgList.get(i).get("id").toString();

		}

		// delete

		orgDao.deleteByOrglId(orgIds);

		for (String modelId : modelIds) {

			orgDao.addModelOrg(modelId, orgIds);

		}

	}

	@Override
	public void batchReleaseModelOrg(String[] modelIds) {
		orgDao.deleteByModelId(modelIds);

	}

	@Override
	public void batchReleaseOrgModel(String[] orgIds) {
		orgDao.deleteByOrglId(orgIds);
	}

	@Override
	public void releaseOneOrgModel(String orgId, String[] modelIds) {

		orgDao.deleteByOrgIdAndModelIds(orgId, modelIds);

	}

	@Override
	public void releaseOneModelOrg(String modelId, String[] orgIds) {
		orgDao.deleteByModelIdAndOrgIds(modelId, orgIds);
	}

	@Override
	public void addAccountAct(String accountId, String checkType) {
		accountDao.updateAccountCheckType(accountId, checkType);

	}

	@Override
	public boolean isAccountExist(String account) {

		return accountDao.selectCountByAccount(account) > 0;

	}

	@Override
	public List<String> getAccountAct(String accountId) {

		return accountDao.selectAccountAct(accountId);
	}

	@Override
	public void updatePassword(String accountId, String password) {
		accountDao.updatePassword(accountId, password);

	}

	@Override
	public Account select(String accountId) {

		return accountDao.select(accountId);
	}

	@Override
	public boolean modelHasProcess(String modelId, String[] orgIds) {

		return orgDao.selectModelOrgInProcess(modelId, orgIds) > 0;
	}

	@Override
	public boolean orgHasProcess(String orgId, String[] modelIds) {

		return orgDao.selectOrgModelInProcess(orgId, modelIds) > 0;
	}

}
